Technotes
Some Techniques for Handling Variables in Apple Guide |
Technote 1075 | October 1996 |
Apple Guide has many advantages over other help systems but also has several drawbacks. One is that it is not easy to keep track of what the user has already done. This becomes a particular problem if you are writing a tutorial. For example, your tutorial might have 10 different lessons which the user may need to complete over several days. How can the user be sure that he or she has gone back to the point they left the tutorial and not skipped stages? One way to do this is to store variables within an application. This Technote also discusses using helper applications with Apple Guide. The following enclosed code sample demonstrates several important techniques that can be used in the creation of a guide file. It demonstrates how to write a background-only helper application and how to use it to store and access variables which are used by the guide. In addition, it shows you how to add a coach mark handler. To download it, just click on the icon below: Apple Guide Variables Code Sample Folder (305K) CONTENTS
Storing Apple Guide Variables in an ApplicationStoring the variables within your application is often the easiest place to put them. You need to do several things:
The examples below just store an array of longs and initialize everything to 0 each time the application is run. For simplicity sake, the codes only going to set them to 0 or 1 and test whether they are 0 or non 0. An unregistered suite of Apple Events 'Vals' is going to be used. This is for demonstration purposes only and you should use your own ID's. The Apple Guide accesses variables 1 to 3, however, as arrays in 'C' start from 0, indexes from the guide are mapped from 1-3 to 0-2. Installing and InitializingYou need to create storage for variables and then initialize them. You may want to store and recall these from a preference file or clear them each time the application is run. Listing 1 contains storage for 3 variables and a context check reference. It also shows how to initializes them and install the handlers. |
Listing 1 Initializing the guide variables and handlers
// Maximum number of values that can be stored by app #define kMaxAGEntries 3 // Storage for values long gAGValues[kMaxAGEntries]; // Storage for context check references AGContextRefNum contextRefNum; void ClearAllAGValues() { long count; for (count=0;count < kMaxAGEntries;count++) gAGValues[count] = 0; } OSErr InitAGVars() { OSErr theErr = noErr; short count; // Clear all the values stored by the application ClearAllAGValues(); // Install context check handler. MyContextCallBack will get called when a // context check of 'Vals' is queried by the Guide theErr = AGInstallContextHandler( NewContextReplyProc(MyContextCallBack), 'Vals', 0, &contextRefNum ); if (theErr) DebugStr("\pGot an Err - AGInstallContextHandler "); // set up the dispatch table for the Apple Events theErr = AEInstallEventHandler( 'Vals', 'Cler', NewAEEventHandlerProc(ClearAGValues), 0, false) ; theErr = AEInstallEventHandler( 'Vals', 'Clr1', NewAEEventHandlerProc(ClearAGValues1), 0, false) ; theErr = AEInstallEventHandler( 'Vals', 'Clr2', NewAEEventHandlerProc(ClearAGValues2), 0, false) ; theErr = AEInstallEventHandler( 'Vals', 'Clr3', NewAEEventHandlerProc(ClearAGValues3), 0, false) ; theErr = AEInstallEventHandler( 'Vals', 'Set1', NewAEEventHandlerProc(SetAGValues1), 0, false) ; theErr = AEInstallEventHandler( 'Vals', 'Set2', NewAEEventHandlerProc(SetAGValues2), 0, false) ; theErr = AEInstallEventHandler( 'Vals', 'Set3', NewAEEventHandlerProc(SetAGValues3), 0, false) ; return theErr; }
Setting and Clearing VariablesSetting and clearing of variables is done by Apple Events. Each event has a specific ID and no passed parameters. You will probably need to make these obvious by their ID. For instance, to set and clear value 1, use the event ID's 'Set1' and 'Clr1' . The source for the handlers can be found in Listing 1. |
Listing 2 Setting and clearing a variable
pascal OSErr SetAGValues1(const AppleEvent *message, const AppleEvent *reply, long refcon) { gAGValues[0] = 1; return( noErr ); } pascal OSErr ClearAGValues1(const AppleEvent *message, const AppleEvent *reply, long refcon) { gAGValues[0] = 0; return( noErr ); }
For ease, you may want to clear all the variables. This is done by event ID 'Cler'.
Listing 3 Clearing all the variables
pascal OSErr ClearAGValues(const AppleEvent *message, const AppleEvent *reply, long refcon) { ClearAllAGValues(); return( noErr ); }
Interrogating VariablesChecking the state of the variables is handled by Apple Guide context checks. There are mechanisms to pass data from a guide file into a context check; therefore, you only need one check which can be used to interrogate all the values. In this case, two longs are passed in the pInputData parameter. The easiest way to access them is to create a structure.
If command contains a 0, then a check is made to see if the value is 0. If it contains a 1, then the check sees it if the value is non-0. Index is used to define which variable to check. |
Listing 5 Context check
pascal OSErr MyContextCallBack( Ptr pInputData, Size inputDataSize, Ptr *ppOutputData, Size *pOutputDataSize, AGAppInfoHdl hAppInfo ) { OSErr theErr = noErr; Boolean checkResult = false; // Check the index is within range if (((PassedAGParamPtr)pInputData)->index <= kMaxAGEntries) // Work out whether we need to return true or false if (((PassedAGParamPtr)pInputData)->command == 1) checkResult = gAGValues[ ((PassedAGParamPtr)pInputData)->index - 1 ] != 0; else checkResult = gAGValues[ ((PassedAGParamPtr)pInputData)->index - 1 ] == 0; // Set up the return values ppOutputData and pOutputDataSize theErr = MySetContextResult ( checkResult, ppOutputData, pOutputDataSize ); return theErr; }
Technotes Previous Technote | Contents | Next Technote |